package com.example.aigc_education.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.aigc_education.common.BusinessException;
import com.example.aigc_education.constant.CacheConstants;
import com.example.aigc_education.domain.Checklist;
import com.example.aigc_education.domain.User;
import com.example.aigc_education.domain.dto.PageDTO;
import com.example.aigc_education.domain.dto.TimingStatusDTO;
import com.example.aigc_education.domain.request.ChecklistQueryRequest;
import com.example.aigc_education.domain.request.TimerEndRequest;
import com.example.aigc_education.domain.request.UpdateChecklistRequest;
import com.example.aigc_education.domain.request.UpdateTimerRequest;
import com.example.aigc_education.domain.vo.ChecklistVO;
import com.example.aigc_education.mapper.ChecklistMapper;
import com.example.aigc_education.mapper.UserMapper;
import com.example.aigc_education.service.ChecklistService;
import com.example.aigc_education.utils.RedisCache;
import com.example.aigc_education.utils.ResultUtil;
import com.example.aigc_education.utils.SecurityUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;


@Service
public class ChecklistServiceImpl extends ServiceImpl<ChecklistMapper, Checklist> implements ChecklistService {
    @Resource
    private ChecklistMapper checklistMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private RedisCache redisCache;

    @Override
    public PageDTO<ChecklistVO> queryChecklistPage(Long userId, ChecklistQueryRequest checklistQueryRequest) {
        LambdaQueryWrapper<Checklist> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Checklist::getUserId, userId);
        //待办已完成不筛选
        queryWrapper.ne(Checklist::getChecklistStatus,2);
        queryWrapper.ne(Checklist::getChecklistStatus,4);

        if (checklistQueryRequest.getChecklistTitle() != null) {
            queryWrapper.like(Checklist::getChecklistTitle, checklistQueryRequest.getChecklistTitle());
        }

        if (checklistQueryRequest.getMustDoDay() != null) {
            queryWrapper.eq(Checklist::getMustDoDay, checklistQueryRequest.getMustDoDay());
        }

        if (checklistQueryRequest.getChecklistType() != null) {
            queryWrapper.eq(Checklist::getChecklistType, checklistQueryRequest.getChecklistType());
        }

        if (checklistQueryRequest.getPriority() != null) {
            queryWrapper.eq(Checklist::getPriority, checklistQueryRequest.getPriority());
        }

        if (checklistQueryRequest.getDeadlineFrom() != null){
            queryWrapper.ge(Checklist::getDeadline, checklistQueryRequest.getDeadlineFrom());
        }

        if (checklistQueryRequest.getDeadlineTo() != null){
            queryWrapper.le(Checklist::getDeadline, checklistQueryRequest.getDeadlineTo());
        }

        if (checklistQueryRequest.isTodayIsDo()){
            queryWrapper.gt(Checklist::getTodayDoTime, 0);
        }

        if (checklistQueryRequest.getChecklistStatus() != null) {
            queryWrapper.eq(Checklist::getChecklistStatus, checklistQueryRequest.getChecklistStatus());
        }

        Page<Checklist> page = checklistQueryRequest.toMpPage("priority",true);

        Page<Checklist> checklistPage = this.page(page, queryWrapper);

        return PageDTO.of(checklistPage, ChecklistVO.class);
    }

    @Override
    public ResultUtil updateChecklistInfo(UpdateChecklistRequest updateChecklistRequest) {
        Checklist checklist = getById(updateChecklistRequest.getChecklistId());
        if (checklist == null){
            return ResultUtil.error("未找到该待办");
        }
        if (!updateChecklistRequest.getTimeDuration().equals(checklist.getTimeDuration()) && !updateChecklistRequest.getTodayDoTime().equals(checklist.getTodayDoTime())){
            return ResultUtil.error("今日完成时间与待办已进行总时间不能同时修改");
        }
         if (updateChecklistRequest.getTimeDuration() > checklist.getTimeDuration()){
             return ResultUtil.error("待办已进行总时间只能设置比原来时间短的数值");
        }
        if (updateChecklistRequest.getTodayDoTime() > checklist.getTodayDoTime()){
            return ResultUtil.error("今日完成时间只能设置比原来时间短的数值");
        };
        Integer newTimeDuration = updateChecklistRequest.getTimeDuration()- (checklist.getTodayDoTime() - updateChecklistRequest.getTodayDoTime());
        checklist.setChecklistTitle(updateChecklistRequest.getChecklistTitle());
        checklist.setPriority(updateChecklistRequest.getPriority());
        checklist.setChecklistType(updateChecklistRequest.getChecklistType());
        checklist.setDeadline(updateChecklistRequest.getDeadline());
        checklist.setMustDoDay(updateChecklistRequest.getMustDoDay());
        checklist.setTimeSpan(updateChecklistRequest.getTimeSpan());
        checklist.setChecklistStatus(updateChecklistRequest.getChecklistStatus());
        checklist.setTodayDoTime(updateChecklistRequest.getTodayDoTime());
        checklist.setTimeDuration(newTimeDuration);
        updateById(checklist);

        return ResultUtil.success("待办修改成功");
    }

    @Override
    public ResultUtil updateAfterTime(TimerEndRequest timerEndRequest) {
        Checklist checklist = getById(timerEndRequest.getChecklistId());
        if (checklist == null){
            return ResultUtil.error("未找到该待办");
        }
        checklist.setTodayDoTime(checklist.getTodayDoTime() + timerEndRequest.getDoTime());
        checklist.setTimeDuration(checklist.getTimeDuration() + timerEndRequest.getDoTime());
        checklist.setTimingDate(LocalDateTime.now());
        checklist.setChecklistStatus(timerEndRequest.getChecklistStatus());
        updateById(checklist);
        redisCache.deleteObject(CacheConstants.CHECKLIST_TIMER_KEY + timerEndRequest.getChecklistId());
        Long userId = SecurityUtils.getUserId();
//        User user = userMapper.selectById(1L);
        User user = userMapper.selectById(userId);
        user.setRunningChecklist(0L);
        userMapper.updateById(user);
        return ResultUtil.success("计时完成");
    }

    @Override
    public List<Checklist> getAllChecklist() {
        try {
            return checklistMapper.selectList(null);
        }catch (Exception e){
            throw new BusinessException("查询待办列表失败");
        }
    }

    @Override
    public void addChecklist(Checklist checklist) {
        try {
            checklistMapper.insert(checklist);
        }catch (Exception e){
            throw new BusinessException("添加待办失败");
        }
    }

    @Override
    public void updateChecklistById(Checklist checklist, Long checklistId) {
        try {
            checklist.setChecklistId(checklistId);
            checklistMapper.updateById(checklist);

        }catch (Exception e){
            throw new BusinessException("更新待办失败");
        }
    }

    @Override
    public void deleteChecklistById(Long checklistId) {
        try {
            checklistMapper.deleteById(checklistId);
        }catch (Exception e){
            throw new BusinessException("删除待办失败");
        }
    }

    @Override
    public ResultUtil startTimer(Long checklistId) {
        try {
            String key = CacheConstants.CHECKLIST_TIMER_KEY + checklistId;
            redisCache.setCacheObject(key,new TimingStatusDTO(0,0,LocalDateTime.now(),0));
            //返回计时待办给前端
            Long userId = SecurityUtils.getUserId();
//            Long userId = 1L;
            User user = userMapper.selectById(userId);
            if (user.getRunningChecklist() != 0) {
                Checklist runningChecklist = checklistMapper.selectById(user.getRunningChecklist());
                String errorMessage = "待办：" + runningChecklist.getChecklistTitle() + "正在运行中，你无法开始新的待办";
                return ResultUtil.error(errorMessage);
            }
            user.setRunningChecklist(checklistId);
            userMapper.updateById(user);
            Checklist checklist = checklistMapper.selectById(checklistId);
            return ResultUtil.success(checklist);
        }catch (Exception e){
            throw new BusinessException("开启计时失败");
        }
    }

    @Override
    public ResultUtil updateTimingStatus(UpdateTimerRequest updateTimerRequest) {
        try {
            String key = CacheConstants.CHECKLIST_TIMER_KEY + updateTimerRequest.getChecklistId();
            redisCache.setCacheObject(key, updateTimerRequest.getTimingStatusDTO());
        } catch (Exception e) {
            throw new BusinessException("修改计时状态失败");
        }
        return ResultUtil.success("计时状态保存成功");
    }

    @Override
    public ResultUtil getTimingStatus(Long checklistId) {
        try {
            String key = CacheConstants.CHECKLIST_TIMER_KEY + checklistId;
            TimingStatusDTO timingStatusDTO = redisCache.getCacheObject(key);
            return ResultUtil.success(timingStatusDTO);
        } catch (Exception e) {
            throw new BusinessException("修改计时状态失败");
        }
    }

    @Override
    public ResultUtil getTodayChecklists(Long userId) {
        LambdaQueryWrapper<Checklist> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Checklist::getUserId, userId);
        //筛选今日进行过的待办
        queryWrapper.eq(Checklist::getChecklistStatus,1).or().eq(Checklist::getChecklistStatus,2);
        List<Checklist> checklists = checklistMapper.selectList(queryWrapper);

        return ResultUtil.success(checklists);
    }
}
